package com.example.sanguogameserver.ai.model;

import com.example.sanguogameserver.dto.battle.BattleTreeInfoColumn;
import com.example.sanguogameserver.dto.battle.BattleTreeInfoRow;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Position {
    public int x;
    public int y;

    public static final Position up = new Position(0, -1);
    public static final Position down = new Position(0, 1);
    public static final Position left = new Position(-1, 0);
    public static final Position right = new Position(1, 0);

    public Position add(Position position) {
        Position newPosition = new Position();
        newPosition.x = this.x + position.x;
        newPosition.y = this.y + position.y;
        return newPosition;
    }


    public Position subtract(Position position) {
        Position newPosition = new Position();
        newPosition.x = this.x - position.x;
        newPosition.y = this.y - position.y;
        return newPosition;
    }

    private List<Position> judgmentMove(List<BattleTreeInfoRow> BattleTreeInfoRows, Position... positions) {
        List<Position> resultPosition = new ArrayList<>();
        for (Position position : positions) {
            if (BattleTreeInfoRows.size() > position.y && BattleTreeInfoRows.get(position.y).getTreeInfoColumns().size() > position.x) {
                // 是否有对方
                BattleTreeInfoColumn BattleTreeInfoColumn = BattleTreeInfoRows.get(position.y).getTreeInfoColumns().get(position.x);
                if (!BattleTreeInfoColumn.isAi() && BattleTreeInfoColumn.getPlayerTreeGeneral() != null) {
                    return null;
                } else if (BattleTreeInfoColumn.getIsMove() != null && BattleTreeInfoColumn.getIsMove()) {
                    resultPosition.add(position);
                }
            }
        }

        return resultPosition;
    }

    public List<Position> topSingleMove(List<BattleTreeInfoRow> BattleTreeInfoRows) {
        Position positionTop = new Position();
        positionTop.x = this.x - 1;
        positionTop.y = this.y;


        Position positionLeft = new Position();
        positionLeft.x = this.x;
        positionLeft.y = this.y - 1;

        Position positionRight = new Position();
        positionRight.x = this.x;
        positionRight.y = this.y + 1;

        return judgmentMove(BattleTreeInfoRows, positionTop, positionLeft, positionRight);
    }

    public List<Position> rightSingleMove(List<BattleTreeInfoRow> BattleTreeInfoRows) {
        Position positionRight = new Position();
        positionRight.x = this.x;
        positionRight.y = this.y + 1;

        Position positionTop = new Position();
        positionTop.x = this.x - 1;
        positionTop.y = this.y;

        Position positionBottom = new Position();
        positionBottom.x = this.x + 1;
        positionBottom.y = this.y;


        return judgmentMove(BattleTreeInfoRows, positionTop, positionBottom, positionRight);
    }

    public List<Position> bottomSingleMove(List<BattleTreeInfoRow> BattleTreeInfoRows) {

        Position positionRight = new Position();
        positionRight.x = this.x;
        positionRight.y = this.y + 1;

        Position positionLeft = new Position();
        positionLeft.x = this.x;
        positionLeft.y = this.y - 1;

        Position positionBottom = new Position();
        positionBottom.x = this.x + 1;
        positionBottom.y = this.y;


        return judgmentMove(BattleTreeInfoRows, positionLeft, positionBottom, positionRight);
    }

    public List<Position> leftSingleMove(List<BattleTreeInfoRow> BattleTreeInfoRows) {

        Position positionTop = new Position();
        positionTop.x = this.x - 1;
        positionTop.y = this.y;

        Position positionLeft = new Position();
        positionLeft.x = this.x;
        positionLeft.y = this.y - 1;

        Position positionBottom = new Position();
        positionBottom.x = this.x + 1;
        positionBottom.y = this.y;


        return judgmentMove(BattleTreeInfoRows, positionLeft, positionBottom, positionTop);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Position position = (Position) o;
        return x == position.x && y == position.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}
